/*
 * CaseInstruction.java
 * 
 * last update: 30.01.2010 by Vlad Badoiu
 * 
 * author:	Vlad Badoiu(vladbadoiu@gmail.com)
 *
 * Obs:
 */
package engine;

import java.util.*;

@SuppressWarnings("serial")
class CaseInstruction extends DefaultInstruction{
	Expression sw;
	Vector<Object> choices;
	int type;

	Instruction choice;

	// v = { expresie, instructiune, expresie, instructiune, ... }  
	// pt. default, expresie = null.
	// ceva de genul 
	//    case (x)
	//       v1:
	//       v2: instructiune;
	//    endcase
	// se scrie { v1, null, v2, instructiune }
	CaseInstruction(NameSpace ns, int db, InstructionDescription desc,
			int type, Expression e, Vector<Object> v, DefaultInstruction next){
		super(ns, db, desc);
		sw = e;  choices = v;  this.type = type;
		for (Enumeration<Object> en = choices.elements(); en.hasMoreElements();)
			try {
				Instruction i = ((Instruction) en.nextElement());
				if (i != null)
					i.append(next);
			} catch (ClassCastException cex) {}
			add(next);
	}

	public Instruction next () {
		if (choice != null)
			return choice;
		return next;
	}

	public void execute()
	throws InterpretTimeException, SimulationStoppedException
	{
		waitToRun();
		BinaryExpression be;
		DefaultInstruction ii, id = null;
		Expression ex;
		choice = null;
		xConsole.trace(toString());
		for (Enumeration<Object> e = choices.elements(); e.hasMoreElements(); ) {
			ex = (Expression)(e.nextElement());
			ii = (DefaultInstruction)(e.nextElement());
			if (ex == null) { id = ii;  continue; }
			try {
				be = new BinaryExpression(ns, sw, "==", ex);
			} catch (ParseException exc){
				throw new InterpretTimeException(desc + ": error:" + exc);
			}
			boolean tmp = false;
			try{
				tmp = be.evaluate().isTrue();
			}catch(InterpretTimeException exc){
				xConsole.dumpStack(exc);
				throw new InterpretTimeException(desc + ": error:" + exc);
			}
			if (tmp) {
				xConsole.debug("case: matched to " + ex);
				while (ii == null && e.hasMoreElements()) { //jump over other
					//expressions to the first instruction:
					ex = (Expression)(e.nextElement());
					ii = (DefaultInstruction)(e.nextElement());
				}
				choice = ii;
				return;
			}
		}
		choice = id;
	}
}





